/* Autostop
 *
 * Copyright (c) Maciej Gajewski, Grzegorz Latarowski
 * http://code.google.com/p/autostop-automaty-drogowe
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or (at your
 * option) any later version. NO WARRANTY OF ANY KIND is expressed or implied.
 */

// system libs
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#include <unistd.h>

// local
#include "registers.h"
#include "tools.h"

// max register value
#define MAX_VALUE	65535

// ============================================================================
// usage info
static void usage()
{
	tools_usage();
	fprintf( stderr, "wr - write registers\n");
	fprintf( stderr, "usage: wr <register address> <value> [value [value [...] ] ]\n");
	fprintf( stderr, "    value formats: 12345 - decimal, 0x12ABC - hex, B10100101 - binary\n");
}

// ============================================================================
// parses string, extracts int in base 2, 10 or 16
int parsenumber( const char* str )
{
	// binary?
	if ( str[0] == 'B' || str[0] == 'b' )
	{
		return strtol( str+1, NULL, 2 );
	}
	else
	{
		// strtol detects '0x' prefix automatically when base is 0
		return strtol( str, NULL, 0 );
	}
}

// ============================================================================
// main
int main( int argc, char** argv )
{
	int address	= -1;	// register address
	int device	= -1;	// file descriptior
	int i;
	
	// check params
	if ( argc < 3 ) {
		usage();
		return 2;
	}
	
	// convert params and check results
	address	= atoi( argv[1] );
	if ( address < 0 ) {
		usage();
		return 3;
	}
	
	// open default device file
	device = open( TOOLS_DEFAULT_DEVICE, O_RDONLY );
	if ( device < 0 ) {
		perror( "could not open " TOOLS_DEFAULT_DEVICE );
		return 1;
	}
	
	// read
	for( i = 2; i < argc; i++ ) {
		int value = -1;
		int result = -1;
		// convert and check register value
		value = parsenumber( argv[i] );

		if ( value < 0 || value > MAX_VALUE ) {
			fprintf( stderr, "%s is not a valid register value\n", argv[i] );
			return 4;
		}
		// write register
		result = write_register( device, address, value );
		// check result
		if ( result < 0 ) {
			fprintf( stderr, "could not write register, is driver loaded?\n");
			return 3;
		}
	}
	
	return 0;
}

// eof

